package cn.wolfcode.wms.service.impl;

import cn.wolfcode.wms.domain.*;
import cn.wolfcode.wms.mapper.*;
import cn.wolfcode.wms.query.QueryObject;
import cn.wolfcode.wms.service.IStockOutcomeBillService;
import cn.wolfcode.wms.util.PageResult;
import cn.wolfcode.wms.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class StockOutcomeBillServiceImpl implements IStockOutcomeBillService {
    @Autowired
    private StockOutcomeBillMapper billMapper; //销售出库
    @Autowired
    private StockOutcomeBillItemMapper itemMapper; //销售出库明细
    @Autowired
    private ProductStockMapper psMapper; //库存
    @Autowired
    private SaleaccountMapper saleaccountMapper; //销售账



    @Override
    public void saveOrUpdate(StockOutcomeBill entity) {
        if (!Optional.ofNullable(entity.getId()).isPresent()) {
            saveBill(entity);
        } else {
            updateBill(entity);
        }
    }



    //更新单据的业务操作
    private void updateBill(StockOutcomeBill entity) {
        StockOutcomeBill old = billMapper.selectByPrimaryKey(entity.getId());
        //判断当前单据必须是未审核状态
        if (entity.getStatus() == StockOutcomeBill.NO_AUDITED) {
            //删除旧的明细
            billMapper.deleteItemsByBillId(entity.getId());
            //重新计算新的小计和总计
            BigDecimal totalNumber = BigDecimal.ZERO;
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (StockOutcomeBillItem item : entity.getItems()) {
                BigDecimal amount = item.getSalePrice().multiply(item.getNumber())
                        .setScale(2, RoundingMode.HALF_UP);
                item.setAmount(amount);
                totalNumber = totalNumber.add(item.getNumber());
                totalAmount = totalAmount.add(amount);
                //最后,直接保存新的明细
                item.setBillId(entity.getId());
                itemMapper.insert(item);
            }
            old.setTotalNumber(totalNumber);
            old.setTotalAmount(totalAmount);
            //同步新的数据
            old.setSn(entity.getSn());
            old.setVdate(entity.getVdate());
            old.setDepot(entity.getDepot());
            old.setClient(entity.getClient());
            //更新单据
            billMapper.updateByPrimaryKey(old);
        }
    }

    //新增单据的业务操作
    private void saveBill(StockOutcomeBill entity) {
        //判断至少有一个明细
        if (entity.getItems().size() == 0) {
            throw new RuntimeException("至少要有一条明细");
        }
        //所有的关键信息必须手动设置一遍
        //单据状态,录入人,录入时间
        entity.setStatus(StockOutcomeBill.NO_AUDITED); //设置未审核状态
        entity.setInputUser(UserContext.getCurrentUser());
        entity.setInputTime(new Date());
        //后台重新计算明细的小计和单据的总计
        BigDecimal totalNumber = BigDecimal.ZERO;
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (StockOutcomeBillItem item : entity.getItems()) {
            BigDecimal amount = item.getSalePrice().multiply(item.getNumber())
                    .setScale(2,RoundingMode.HALF_UP);
            item.setAmount(amount);
            totalNumber = totalNumber.add(item.getNumber());
            totalAmount = totalAmount.add(amount);
        }
        //累加到总计上
        entity.setTotalNumber(totalNumber);
        entity.setTotalAmount(totalAmount);
        //保存到数据库
        billMapper.insert(entity);
        //每个明细设置单据id,保存到数据库
        for (StockOutcomeBillItem item : entity.getItems()) {
            item.setBillId(entity.getId());
            itemMapper.insert(item);
        }
    }




    @Override
    public void delete(Long id) {
        //判断当前单据必须是未审核状态
        StockOutcomeBill old = billMapper.selectByPrimaryKey(id);
        if (old.getStatus() == StockOutcomeBill.NO_AUDITED) {
            //先删除明细再删除单据
            billMapper.deleteItemsByBillId(id);
        }
        billMapper.deleteByPrimaryKey(id);
    }

    @Override
    public StockOutcomeBill get(Long id) {
        return billMapper.selectByPrimaryKey(id);
    }


    @Override
    public void audit(Long id) {
        //判断当前单据必须是未审核状态
        StockOutcomeBill bill = billMapper.selectByPrimaryKey(id);
        if (bill.getStatus() == StockOutcomeBill.NO_AUDITED) {
            //获取到仓库
            Depot depot = bill.getDepot();
            //拿到出库的明细
            for (StockOutcomeBillItem item : bill.getItems()) {
                //查询当前仓库中是否有该商品
                Product p = item.getProduct();
                ProductStock ps = psMapper.selectByProductIdAndDepotId(p.getId(), depot.getId());
                //如果没有库存
                if (!Optional.ofNullable(ps).isPresent()) {
                    String msg = "仓库:" + depot.getName() + "没有商品:" + p.getName() + "的库存";
                    throw new RuntimeException(msg);
                }
                //如果有库存,检查库存是否足够
                if (item.getNumber().compareTo(ps.getStoreNumber()) > 0) {
                    String msg = "仓库:"+ depot.getName() +"中商品:"+ p.getName() +"的库存是:"+ ps.getStoreNumber()
                            +",不足出库的数量:" + item.getNumber();
                    throw new RuntimeException(msg);
                }
                //库存充足,更新库存数量和总价
                //库存数量:原来的库存 - 销售出去的数量
                BigDecimal stockNumber = ps.getStoreNumber().subtract(item.getNumber());
                ps.setStoreNumber(stockNumber);
                //总价:原先的总价 - 销售出去的数量 * 库存价格
                BigDecimal amount = ps.getAmount().subtract(item.getNumber().multiply(ps.getPrice()));
                ps.setAmount(amount.setScale(2, RoundingMode.HALF_UP));
                psMapper.updateByPrimaryKey(ps);

                //记录销售账
                Saleaccount sa = new Saleaccount();
                sa.setVdate(new Date());
                sa.setNumber(item.getNumber());
                sa.setCostprice(ps.getPrice());
                sa.setCostamount(ps.getPrice().multiply(item.getNumber())
                        .setScale(2, RoundingMode.HALF_UP));
                sa.setSaleprice(item.getSalePrice());
                sa.setSaleamount(item.getAmount());
                sa.setProduct(item.getProduct());
                sa.setSaleman(bill.getInputUser());
                sa.setClient(bill.getClient());
                saleaccountMapper.insert(sa);
            }
            //设置状态为审核
            bill.setStatus(StockOutcomeBill.AUDITED);
            bill.setAuditor(UserContext.getCurrentUser());
            bill.setAuditTime(new Date());
            billMapper.audit(bill);
        }

    }

    @Override
    public PageResult query(QueryObject qo) {
        Integer rows = billMapper.queryForCount(qo);
        if (rows == 0){
            return PageResult.EMPTY_RESULT;
        }
        List<StockOutcomeBill> list = billMapper.queryForList(qo);
        PageResult result = new PageResult(qo.getCurrentPage(), qo.getPageSize(), list, rows);
        return result;
    }
}
